package com.aecc.api.util;

import java.text.SimpleDateFormat;
import java.util.Locale;
import java.util.TimeZone;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;

import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;

/**
 * 基于jackson的json工具类
 * @author admin
 *
 */
@Slf4j
public class JSONUtil {
	private static final ObjectMapper mapper = new ObjectMapper();
	
	static {
		// 对于空的对象转json的时候不抛出错误
		mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
		// 允许属性名称没有引号
		mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
		// 允许单引号
		mapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
		// 设置输入时忽略在json字符串中存在但在java对象实际没有的属性
		mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
		// 属性为 空（""） 或者为 NULL 都不序列化，则返回的json是没有这个字段的。这样对移动端会更省流量
		mapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
		// 指定日期格式，yyyy-MM-dd HH:mm:ss
		mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
		mapper.setLocale(Locale.SIMPLIFIED_CHINESE);
		mapper.setTimeZone(TimeZone.getTimeZone("GMT+8"));	
		mapper.findAndRegisterModules();
	}
	
	/**
	 * 对象序列化为JSON字符串
	 * @param data
	 * @return
	 */
	public static String toJSONString(Object data) {
		if(data == null) {
			return null;
		}
		String json = null;
		try {
			json = mapper.writeValueAsString(data);
		} catch (JsonProcessingException e) {
			// TODO Auto-generated catch block
			log.error("[{}] toJsonString error：{{}}", data.getClass().getSimpleName(), e);
		}
		return json;
	}
	
	/**
	 * JSON字符串反序列化为对象
	 * @param <T>
	 * @param json
	 * @param clazz
	 * @return
	 */
	public static <T> T parseObject(@NonNull String json, Class<T> clazz) {
		T t = null;
        try {
            t = mapper.readValue(json, clazz);
        } catch (Exception e) {
            log.error("parse json [{}] to class [{}] error：{{}}", json, clazz.getSimpleName(), e);
        }
        return t;
	}
	
	/**
	 * JSON字符串反序列化为对象，可转换复杂类型
	 * @param <T>
	 * @param json
	 * @param clazz
	 * @param parameterClasses
	 * @return
	 */
	public static <T> T parseObject(@NonNull String json, Class<T> clazz, Class<?>... parameterClasses) {
		JavaType javaType = mapper.getTypeFactory().constructParametricType(clazz, parameterClasses);
		T t = null;
		try {
			t = mapper.readValue(json, javaType);
		} catch (JsonProcessingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return t;
	}
		
	public static ObjectMapper getObjectMapper() {
		return mapper;
	}
	
}
